package com.xuecheng.content.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.AuthInfo;
import com.xuecheng.commons.model.vo.CourseBaseVo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.CoursePub;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.*;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-30
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    // 课程信息分页查询
    @Override
    public ResponseResult findByPage(PageRequest request, CourseDto dto) {
        // 1.构建分页
        Page<CourseBase> page = new Page<>(request.getPageNo(), request.getPageSize());
        // 2.构建条件
        LambdaQueryWrapper<CourseBase> qw = new LambdaQueryWrapper<>();
        // 课程名称
        String courseName = dto.getCourseName();
        qw.like(StrUtil.isNotBlank(courseName), CourseBase::getName, courseName);
        // 课程状态
        String auditStatus = dto.getAuditStatus();
        qw.eq(StrUtil.isNotBlank(auditStatus), CourseBase::getAuditStatus, auditStatus);
        // 课程类型
        String teachmode = dto.getTeachmode();
        qw.eq(StrUtil.isNotBlank(teachmode), CourseBase::getTeachmode, teachmode);

        // 3.执行分页查询
        page = this.page(page, qw);
        // 4.转vo
        List<CourseBase> courseBaseList = page.getRecords();
        List<CourseBaseVo> voList = BeanHelper.copyWithCollection(courseBaseList, CourseBaseVo.class);
        // 5.返回分页结果
        return PageResponseResult.okResult(page.getTotal(), voList);
    }


    @Autowired
    private TeachplanService teachplanService;

    // 课程信息新增
    @Override
    public ResponseResult saveCourseBase(CourseBaseDto dto) {
        // 1.校验参数合法性
        if (StrUtil.isBlank(dto.getName()) || StrUtil.isBlank(dto.getTags())) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        // 2.dto转courseBase
        CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
        // 3.补充字段信息
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS); // 课程状态（未提交）
        courseBase.setCreateDate(DateUtil.date());// 创建时间
        courseBase.setPlanNum(0); // 章节数

        // 4.保存数据库
        boolean isSuccess = this.save(courseBase);
        if (!isSuccess) {
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        // 5.初始化课程一级大纲（待定）
        Teachplan teachplan = new Teachplan();
        teachplan.setPname(courseBase.getName()); // 课程计划名称
        teachplan.setParentid(0L); // 父节点id
        teachplan.setGrade(1); // 一级大纲
        teachplan.setDescription(courseBase.getDescription()); // 介绍
        teachplan.setCourseId(courseBase.getId()); // 课程id
        teachplan.setCreateDate(DateUtil.date());// 创建时间
        teachplanService.save(teachplan);

        // 6.返回结果
        Map map = new HashMap();
        map.put("courseBaseId", courseBase.getId());
        return ResponseResult.okResult(map);
    }

    // 课程信息修改
    @Override
    public ResponseResult updateCourseBase(CourseBaseDto dto) {
        // 1.根据课程id查询数据库
        CourseBase courseBase = this.getById(dto.getId());
        // 2.判断课程状态
        String auditStatus = courseBase.getAuditStatus();
        if (StrUtil.equals(auditStatus, CourseConstants.AUDIT_COMMIT_STATUS) ||
                StrUtil.equals(auditStatus, CourseConstants.AUDIT_PASTED_STATUS) ||
                StrUtil.equals(auditStatus, CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        // 3.dto->courseBase
        // CourseBase params = BeanHelper.copyProperties(dto, CourseBase.class);
        BeanUtil.copyProperties(dto, courseBase);
        // 4.更新数据库
        boolean isSuccess = this.updateById(courseBase);
        if (!isSuccess) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        // 5.更新课程一级大纲（待定）
        // 5-1 条件
        LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
        qw.eq(Teachplan::getCourseId, courseBase.getId()); // 根据课程id
        qw.eq(Teachplan::getGrade, 1L); // 一级大纲
        // 5-2 指定更新字段
        Teachplan teachplan = new Teachplan();
        teachplan.setPname(courseBase.getName()); // 课程计划名称
        teachplan.setDescription(courseBase.getDescription()); // 介绍
        // 5-3 更新数据库
        // update tb_teachplan set pname = ? , description = ? where course_id = ? and grad = ?
        teachplanService.update(teachplan, qw);

        // 6.返回结果
        Map map = new HashMap();
        map.put("courseBaseId", courseBase.getId());
        return ResponseResult.okResult(map);
    }

    // 课程信息删除
    @Override
    public ResponseResult deleteCourseBaseById(Long courseId) {
        // 1.根据课程id查询数据库
        CourseBase courseBase = this.getById(courseId);
        // 2.判断课程状态是否为已发布
        String auditStatus = courseBase.getAuditStatus();
        if (StrUtil.equals(auditStatus, CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }

        // 如果该课程下有课程章节，不允许删除
        // -1 查询该课程下章节数量
        LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
        qw.eq(Teachplan::getCourseId,courseId );
        long count = teachplanService.count(qw);
        if (count>1) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }

        // 3.根据id删除数据库
        this.removeById(courseId);

        // 删除一级大纲
        teachplanService.remove(qw);

        // 4.返回成功
        return ResponseResult.okResult();
    }

    // 提交审核
    @Override
    public ResponseResult commit(Long courseBaseId) {
        // 1.创建课程信息
        CourseBase courseBase = new CourseBase();
        // 2.设置数据
        courseBase.setId(courseBaseId);
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        // 3.更新数据库
        this.updateById(courseBase);
        return ResponseResult.okResult();
    }

    // 平台审核
    @Override
    public ResponseResult approve(CourseAuditDto dto) {
        // 1.查询课程信息
        CourseBase courseBase = this.getById(dto.getCourseBaseId());
        // 2.修改状态和内容
        courseBase.setAuditStatus(dto.getAuditStatus());
        courseBase.setAuditMind(dto.getAuditMind());
        // 3.更新数据库
        this.updateById(courseBase);
        return ResponseResult.okResult();
    }

    @Autowired
    private CoursePubService coursePubService;

    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private PubPageService pubPageService;


    //课程下架
    @Override
    public ResponseResult offline(Long courseId) {
        //1判断课程是否可以更改
        if (courseId==null){
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //2.查看课程
        CourseBase courseBase = courseBaseService.getById(courseId);
        //2.1判断课程状态是不是已发布
        if (!courseBase.getAuditStatus().equals(CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //2.2修改课程状态
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNLINE_STATUS);
        //2.3更新数据库
        courseBaseService.updateById(courseBase);
        //3.删除发布的课程信息
        //3.1构建删除的条件
        LambdaQueryWrapper<CoursePub> qw = new LambdaQueryWrapper<>();
        qw.eq(CoursePub::getCourseId,courseId);
        //3.2删除课程发布信息
        coursePubService.remove(qw);
        //4.删除minion中的数据
        pubPageService.delete(courseId+".html");
        //5.发送mq消息
        rabbitTemplate.convertAndSend("content-exchange","course.pub1" , courseId);
        //6.返回参数
        return ResponseResult.okResult();
    }

}
